mod error;
mod tesseract;

use std::fs;
use std::io::Write; // bring trait into scope

use ndarray::Array3;
use std::collections::HashMap;
use tesseract::{get_tesseract_version, image_to_string, Args, Image};

pub fn ocr_test() {
  // create an Image object by specifying a path or alternatively an image array in (height, width, channel) format
  // if path is an empty string -> rusty-tesseract tries to use the ndarray

  // you can use the new function
  let img = Image::new(
    String::from("enterRandCode.jpeg"),
    Array3::<u8>::zeros((100, 100, 3)),
  );

  // or instantiate Image struct directly
  // let mut img = Image {
  //   path: String::from("enterRandCode.jpeg"),
  //   ndarray: Array3::<u8>::zeros((100, 100, 3)), // example: creates an 100x100 pixel image with 3 colour channels (RGB)
  // };

  // use default_args to call a function if no particular config is needed
  // let default_args = Args::new();

  let tesseract_version = get_tesseract_version();
  println!("The tesseract version is: {:?}", tesseract_version);

  // fill your own argument struct if needed
  let mut image_to_string_args = Args {
    out_filename: "out",
    lang: "chi_sim", // eng, chi_sim
    config: HashMap::new(),
    dpi: 150,
    boxfile: false,
  };
  image_to_string_args.config.insert("psm", "6");
  image_to_string_args.config.insert("oem", "3");

  let output = image_to_string(&img, image_to_string_args);
  println!("\nThe String output is: {:?}", output.Output_STRING);

  // let mut image_to_boxes_args = Args {
  //   out_filename: "font_name.font.exp0",
  //   lang: "eng",
  //   config: HashMap::new(),
  //   dpi: 150,
  //   boxfile: true,
  // };
  // image_to_boxes_args.config.insert("psm", "6");
  // image_to_boxes_args.config.insert("oem", "3");

  // // boxes printed in OUTPUT_DICT or OUTPUT_DATAFRAME format store the Key as a string (i.e. the character) and
  // // store the value as a list of strings (if the same character occurs more than once)
  // let boxes = tesseract::image_to_boxes(&img, image_to_boxes_args);
  // println!("\nThe Boxfile output is: {:?}", boxes.Output_DATAFRAME);

  // // image_to_data prints out both image_to_string and image_to_boxes information + a creates a TSV table with confidences
  // let data = tesseract::image_to_data(&img, default_args);
  // println!("\nThe data output is: {:?}", data.Output_DICT);
  // println!("\nThe confidence tesstable can be found in the [out_filename].tsv file!\n");
}

pub fn ocr_captcha(img_data: &mut[u8]) -> String {
  // ... later in code
  let path = "tmp_ocr/captcha.jpeg";
  let mut file = fs::OpenOptions::new()
    .write(true)
    .create(true)
    // either use ? or unwrap since it returns a Result
    .open(path)
    .unwrap();

  file.write_all(img_data).expect("ocr captcha write fail");

  let img = Image::new(String::from(path), Array3::<u8>::zeros((100, 100, 3)),);

  let mut image_to_string_args = Args {
    out_filename: "out",
    lang: "eng", // eng, chi_sim
    config: HashMap::new(),
    dpi: 150,
    boxfile: false,
  };
  image_to_string_args.config.insert("psm", "6");
  image_to_string_args.config.insert("oem", "3");

  let output = image_to_string(&img, image_to_string_args);
  println!("\nThe String output is: {:?}", output.Output_STRING);

  return output.Output_STRING;
}
